package com.example.stock.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.example.stock.entity.Stock;
import com.example.stock.entity.StockDataResponse;
import com.example.stock.tencent.DingDingBot;
import com.example.stock.tencent.StockBean;
import com.example.stock.tencent.TencentProxy;
import com.example.stock.util.DateUtil;
import com.example.stock.util.HolidayUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.text.ParseException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.HashMap;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

/**
 * @Author tanlvxu
 * @Date 2024/12/19 10:45
 * @Description 量比服务
 */
@Service
@Slf4j
public class VolumeCompareService {

    @Autowired
    private IStockService iStockService;

    @Autowired
    private LastMaxStockService lastMaxStockService;

    @Autowired
    private TencentProxy tencentProxy;

    public String getLastGzr(LocalDateTime nowLocal) throws ParseException {
        String calcDate = null;
        for (int i = 1; i < 10; i++) {
            nowLocal = nowLocal.plusDays(-1);
            // 定义日期时间格式
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            // 格式化当前时间
            String formattedNow = nowLocal.format(formatter);
            String workingDay = HolidayUtil.isWorkingDay(formattedNow);
            if("0".equals(workingDay)){
                calcDate =  formattedNow;
                break;
            }
        }
        return calcDate;
    }

    /**
     * 将内容追加写入到文件
     * @param content 要写入的内容
     */
    private void appendToFile(String content) {
        try {
            // 添加时间戳和分隔符
            String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            String formattedContent = "==================== " + timestamp + " ====================\n" 
                                    + content + "\n\n";
            
            // 使用相对路径，文件将创建在项目根目录
            Path filePath = Paths.get("stock-analysis.txt");
            
            // 确保父目录存在（对于相对路径通常不需要，但保险起见）
            Path parentDir = filePath.getParent();
            if (parentDir != null && !Files.exists(parentDir)) {
                Files.createDirectories(parentDir);
            }
            
            // 写入文件，CREATE选项会自动创建文件，APPEND选项追加内容
            Files.write(filePath, 
                       formattedContent.getBytes(StandardCharsets.UTF_8), 
                       StandardOpenOption.CREATE, 
                       StandardOpenOption.APPEND);
                       
            log.debug("成功写入文件: {}", filePath.toAbsolutePath());
        } catch (IOException e) {
            log.error("写入文件失败: {}, 回退到控制台输出", e.getMessage(), e);
            log.info(content);
        } catch (Exception e) {
            log.error("写入文件时发生未知错误: {}, 回退到控制台输出", e.getMessage(), e);
            log.info(content);
        }
    }    /**
     * 量比
     * @param stockBeans
     */
    public void volumeCompare(List<StockBean> stockBeans) {
        try {
            List<Map<String,Stock>> allOrgStocks = new ArrayList<>();
            int calcDay = 0;
            LocalDateTime curDay = null;
            // 定义日期时间格式
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            // 获取当前时间
            LocalDateTime nowLocal = LocalDateTime.now();
            for(int i = 1; i <= 20 && allOrgStocks.size() < 6; i++) {
                // 计算前i天的日期
                LocalDateTime targetDay = nowLocal.minusDays(i);
                String formattedNow = targetDay.format(formatter);
                // 判断是否为工作日
                if("0".equals(HolidayUtil.isWorkingDay(formattedNow))){
                    Date date = Date.from(nowLocal.atZone(ZoneId.systemDefault()).toInstant());
                    Date dayBegin = DateUtil.getDayBegin(date);
                    Date dayEnd = DateUtil.getDayEnd(date);
                    List<Stock> list1 = iStockService.list(Wrappers.<Stock>lambdaQuery().eq(Stock::getCalcType, 3).ge(Stock::getCalcTime, dayBegin).le(Stock::getCalcTime, dayEnd));
                    if(list1.size() == 0){
                        break;
                    }
                    // 将股票数据转换为Map并添加到结果列表中
                    Map<String, Stock> stockMap = list1.stream()
                            .collect(Collectors.toMap(Stock::getCode, Function.identity()));

                    allOrgStocks.add(stockMap);
                    if(allOrgStocks.size() >= 5){
                        break;
                    }
                }
            }
            //昨日涨停
            Map<String, Stock> lastHighMap = lastMaxStockService.getLastHighMap();
            String lastGzr = getLastGzr(nowLocal);
            String lastGzr2 = getLastGzr(LocalDate.parse(lastGzr, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atStartOfDay());
            List<Stock> stocks2 = iStockService.listByCalcTimeAndCalcType(lastGzr2, 3);
            //前日涨停
            Map<String, Stock> zhangtingStocks2 = stocks2.stream().filter(o -> o.getChangePercent() < 11 && ObjectUtil.equal(o.getPriceNow(), o.getHighLimit()) && !o.getName().contains("ST")).collect(Collectors.toMap(Stock::getCode, Function.identity()));
            List<Stock> resStock = new ArrayList<>();
            lastHighMap.forEach((key, stock)->{
                Stock stock2 = zhangtingStocks2.get(key);
                if(stock2 == null){
                    resStock.add(stock);
                }
            });
            Map<String, Stock> resStockMap = resStock.stream().collect(Collectors.toMap(Stock::getCode, Function.identity()));
            // 获取所有股票代码
            Set<String> codes = resStockMap.keySet();

            Map<String, StockBean> stockBeanMap = stockBeans.stream().collect(Collectors.toMap(StockBean::getCode, Function.identity()));
            List<StockBean> res = new ArrayList<>();
            for (String code : codes) {
                StockBean stockBean = stockBeanMap.get(code);
                float totalVolume = 0;
                int count = 0;
                for (Map<String, Stock> map : allOrgStocks){
                    String volume = map.get(code).getVolume();
                    totalVolume += Integer.parseInt(volume);
                    count ++;
                }
                long volume = stockBean.getVolume();
                double compare = volume*count*240/totalVolume;
                stockBean.setVolumeCompare(compare);
                res.add(stockBean);
            }
            res =  res.stream().filter(o -> o.getVolumeCompare() >= 10 ).sorted(Comparator.comparingDouble(StockBean::getVolumeCompare).reversed()).collect(Collectors.toList());

            StringBuilder stringBuilder = new StringBuilder();
            String title = "### **当日接力涨停池"+res.size()+"只股票**\n" ;
            stringBuilder.append(title);
            for (int i = 0; i < res.size(); i++) {
                StockBean stockBean = res.get(i);
                stringBuilder.append(String.format("- %s-%s-量比%s\n",stockBean.getName(),stockBean.getCode(),stockBean.getVolumeCompare()+""));
            }
            DingDingBot.sendMarkDown(title,stringBuilder.toString());


        } catch (ParseException e) {
            throw new RuntimeException(e);
        }

    }

    public void volumeCompare2(List<StockBean> stockBeans, String curDay) {

            try {
                List<Map<String, Stock>> allOrgStocks = new ArrayList<>();
                String calcDay = curDay;
                for (int i = 1; i <= 20 && allOrgStocks.size() < 6; i++) {
                    // 计算前i天的日期
                    calcDay = getLastGzr(LocalDate.parse(calcDay, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atStartOfDay());
                    // 判断是否为工作日
                    if ("0".equals(HolidayUtil.isWorkingDay(calcDay))) {
                        List<Stock> list1 = iStockService.listByCalcTimeAndCalcType(calcDay,3);
                        if (list1.size() == 0) {
                            break;
                        }
                        // 将股票数据转换为Map并添加到结果列表中
                        Map<String, Stock> stockMap = list1.stream()
                                .collect(Collectors.toMap(Stock::getCode, Function.identity()));

                        allOrgStocks.add(stockMap);
                        if (allOrgStocks.size() >= 5) {
                            break;
                        }
                    }
                }
//                List<Stock> stockBeans  = iStockService.listByCalcTimeAndCalcType(curDay, 1);
                //计算昨日涨停
                String lastDay = getLastGzr(LocalDate.parse(curDay, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atStartOfDay());

                List<Stock> lastStocks = iStockService.listByCalcTimeAndCalcType(lastDay, 3);
                //昨日涨停
                Map<String, Stock> lastHighMap = lastStocks.stream().filter(o -> o.getChangePercent() < 11 && ObjectUtil.equal(o.getPriceNow(), o.getHighLimit()) && !o.getName().contains("ST")).collect(Collectors.toMap(Stock::getCode, Function.identity()));
                String lastGzr2 = getLastGzr(LocalDate.parse(lastDay, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atStartOfDay());
                List<Stock> stocks2 = iStockService.listByCalcTimeAndCalcType(lastGzr2, 3);
                //前日涨停
                Map<String, Stock> zhangtingStocks2 = stocks2.stream().filter(o -> o.getChangePercent() < 11 && ObjectUtil.equal(o.getPriceNow(), o.getHighLimit()) && !o.getName().contains("ST")).collect(Collectors.toMap(Stock::getCode, Function.identity()));
                List<Stock> resStock = new ArrayList<>();
                lastHighMap.forEach((key, stock) -> {
                    Stock stock2 = zhangtingStocks2.get(key);
                    if (stock2 == null) {
                        resStock.add(stock);
                    }
                });
                Map<String, Stock> resStockMap = resStock.stream().collect(Collectors.toMap(Stock::getCode, Function.identity()));
                // 获取所有股票代码
                Set<String> codes = resStockMap.keySet();

                Map<String, StockBean> stockBeanMap = stockBeans.stream().collect(Collectors.toMap(StockBean::getCode, Function.identity()));
                List<StockBean> res = new ArrayList<>();
                for (String code : codes) {
                    StockBean stockBean = stockBeanMap.get(code);
                    long totalVolume = 0;
                    int count = 0;
                    for (Map<String, Stock> map : allOrgStocks) {
                        if(map.get(code) == null){
                            continue;
                        }
                        String volume = map.get(code).getVolume();
                        totalVolume += Integer.parseInt(volume);
                        count++;
                    }
                    long volume = stockBean.getVolume();
                    double compare = volume * count * 240 *1.0f/ totalVolume;
                    stockBean.setVolumeCompare(compare);
                    res.add(stockBean);
                }
                res = res.stream().filter(o -> o.getVolumeCompare() >= 10 && o.getChangePercent() > 1.0 && o.getChangePercent()<=6).sorted(Comparator.comparingDouble(StockBean::getVolumeCompare).reversed()).collect(Collectors.toList());

                StringBuilder stringBuilder = new StringBuilder();
                String title = "### **"+curDay+"当日接力涨停池" + res.size() + "只股票**\n";
                stringBuilder.append(title);
                List<Stock> resstockBeans  = iStockService.listByCalcTimeAndCalcType(curDay, 3);
                Map<String, Stock> resMap = resstockBeans.stream().collect(Collectors.toMap(Stock::getCode, Function.identity()));
                for (int i = 0; i < res.size(); i++) {
                    StockBean stockBean = res.get(i);
                    String weipan = "";
                    if(resMap.containsKey(stockBean.getCode())){
                        weipan = resMap.getOrDefault(stockBean.getCode(),new Stock()).getChangePercent() + "";
                    }
                    stringBuilder.append(String.format("- %s-%s-量比%s,开盘%s,流通市值%s\n", stockBean.getName(), stockBean.getCode(), (int)stockBean.getVolumeCompare() + " 收盘："+weipan,stockBean.getChangePercent(),stockBean.getCirculatingCap()));
                }
                DingDingBot.sendMarkDown(title, stringBuilder.toString());
//                log.info(stringBuilder.toString());

            } catch (ParseException e) {
                throw new RuntimeException(e);
            }
    }


    public static boolean isCals = false;

//    @PostConstruct
    public void testss(String curDay,boolean isCalssss){
//        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        // 格式化当前时间
//        String curDay =  LocalDateTime.now().format(formatter);

//        String curDay = "2025-01-09";//6
        isCals = isCalssss;

        List<Stock> list1 = iStockService.listByCalcTimeAndCalcType(curDay,1);

        List<StockBean> stockBeans = new ArrayList<>();
        for (int i = 0; i < list1.size(); i++) {
            Stock stock = list1.get(i);
            StockBean stockBean = new StockBean();
            BeanUtil.copyProperties(stock, stockBean,"time");
            stockBean.setCalcTime(curDay);
            stockBeans.add(stockBean);
        }
//        volumeCompare2(stockBeans,curDay);
        volumeCompare2111(stockBeans,curDay);
    }

        public String getNextGzr(LocalDateTime nowLocal) throws ParseException {
            String calcDate = null;
            for (int i = 1; i < 10; i++) {
                nowLocal = nowLocal.plusDays(1);
                // 定义日期时间格式
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                // 格式化当前时间
                String formattedNow = nowLocal.format(formatter);
                String workingDay = HolidayUtil.isWorkingDay(formattedNow);
                if ("0".equals(workingDay)) {
                    calcDate = formattedNow;
                    break;
                }
            }
            return calcDate;
        }

    @PostConstruct
    public void testss2() throws ParseException {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
//         格式化当前时间
//        String curDay =  LocalDateTime.now().format(formatter);

        String curDay = "2025-05-08";//6
        isCals = true;

        for (int j = 0; j < 2000; j++) {
            curDay = getNextGzr(LocalDate.parse(curDay, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atStartOfDay());

            List<Stock> list1 = iStockService.listByCalcTimeAndCalcType(curDay,1);

            List<StockBean> stockBeans = new ArrayList<>();
            for (int i = 0; i < list1.size(); i++) {
                Stock stock = list1.get(i);
                StockBean stockBean = new StockBean();
                BeanUtil.copyProperties(stock, stockBean,"time");
                stockBean.setCalcTime(curDay);
                stockBeans.add(stockBean);
            }
            System.out.println("计算日期："+curDay);
//        volumeCompare2(stockBeans,curDay);
            volumeCompare2111(stockBeans,curDay);
            if(curDay.equals("2025-07-25")){
                break;
            }
        }
    }


    public void volumeCompare2111(List<StockBean> stockBeans, String curDay ) {


        try {
            List<Map<String, Stock>> allOrgStocks = new ArrayList<>();
            String calcDay = curDay;
            for (int i = 1; i <= 20 && allOrgStocks.size() < 6; i++) {
                // 计算前i天的日期
                calcDay = getLastGzr(LocalDate.parse(calcDay, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atStartOfDay());
                // 判断是否为工作日
                if ("0".equals(HolidayUtil.isWorkingDay(calcDay))) {
                    List<Stock> list1 = iStockService.listByCalcTimeAndCalcType(calcDay,3);
                    if (list1.size() == 0) {
                        break;
                    }
                    // 将股票数据转换为Map并添加到结果列表中
                    Map<String, Stock> stockMap = list1.stream()
                            .collect(Collectors.toMap(Stock::getCode, Function.identity(),(a,b)->a));

                    allOrgStocks.add(stockMap);
                    if (allOrgStocks.size() >= 5) {
                        break;
                    }
                }
            }
//                List<Stock> stockBeans  = iStockService.listByCalcTimeAndCalcType(curDay, 1);
            //计算昨日涨停
            String lastDay = getLastGzr(LocalDate.parse(curDay, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atStartOfDay());

            List<Stock> lastStocks = iStockService.listByCalcTimeAndCalcType(lastDay, 3);
            //昨日涨停
            Map<String, Stock> lastHighMap = lastStocks.stream().collect(Collectors.toMap(Stock::getCode, Function.identity()));
            
            //获取昨日早盘数据
            List<Stock> lastMorningStocks = iStockService.listByCalcTimeAndCalcType(lastDay, 1);
            Map<String, Stock> lastMorningMap = lastMorningStocks.stream().collect(Collectors.toMap(Stock::getCode, Function.identity(), (a,b)->a));
            
            //计算昨日早盘量比
            Map<String, Double> lastMorningVolumeCompareMap = new HashMap<>();
            for (Stock morningStock : lastMorningStocks) {
                long totalVolume = 0;
                int count = 0;
                for (Map<String, Stock> map : allOrgStocks) {
                    if(map.get(morningStock.getCode()) == null) continue;
                    String volume = map.get(morningStock.getCode()).getVolume();
                    totalVolume += Integer.parseInt(volume);
                    count++;
                }
                if(count > 0) {
                    long volume = Long.parseLong(morningStock.getVolume());
                    double compare = volume * count * 240 * 1.0f / totalVolume;
                    lastMorningVolumeCompareMap.put(morningStock.getCode(), compare);
                }
            }            String lastGzr2 = getLastGzr(LocalDate.parse(lastDay, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atStartOfDay());
            List<Stock> stocks2 = iStockService.listByCalcTimeAndCalcType(lastGzr2, 3);
            //filter(o -> o.getChangePercent() < 11 && ObjectUtil.equal(o.getPriceNow(), o.getHighLimit()) && !o.getName().contains("ST"))
            //前日涨停
            Map<String, Stock> zhangtingStocks2 = stocks2.stream().collect(Collectors.toMap(Stock::getCode, Function.identity()));
            List<Stock> resStock = new ArrayList<>();
//            lastHighMap.forEach((key, stock) -> {
//                Stock stock2 = zhangtingStocks2.get(key);
//                if (stock2 == null) {
//                    resStock.add(stock);
//                }
//            });
            for (int i = 0; i < lastStocks.size(); i++) {
                Stock stock = lastStocks.get(i);
                Stock stock2 = zhangtingStocks2.get(stock.getCode());
                if(stock != null && stock2!=null && ObjectUtil.notEqual(stock.getPriceNow(), stock.getHighLimit()) && stock.getHighLimit()>4 && stock.getLowLimit()>0 && !stock.getName().contains("ST")
                   && (stock.getHighLimit() - stock2.getPriceNow())/stock2.getPriceNow() <0.13){
                    resStock.add(stock);
                }
            }

            Map<String, Stock> resStockMap = resStock.stream().collect(Collectors.toMap(Stock::getCode, Function.identity(),(a,b)->a));
            // 获取所有股票代码
            Set<String> codes = resStockMap.keySet();

            Map<String, StockBean> stockBeanMap = stockBeans.stream().collect(Collectors.toMap(StockBean::getCode, Function.identity(),(a,b)->a));
            List<StockBean> res = new ArrayList<>();
            for (String code : codes) {
                StockBean stockBean = stockBeanMap.get(code);
                long totalVolume = 0;
                int count = 0;
                for (Map<String, Stock> map : allOrgStocks) {
                    if(map.get(code) == null){
                        continue;
                    }
                    String volume = map.get(code).getVolume();
                    totalVolume += Integer.parseInt(volume);
                    count++;
                }
                if(stockBean == null){
                    continue;
                }
                long volume = stockBean.getVolume();
                double compare = volume * count * 240 *1.0f/ totalVolume;
                stockBean.setVolumeCompare(compare);
                res.add(stockBean);
            }
            res = res.stream().filter(o -> o.getVolumeCompare() >= 10 && o.getChangePercent() > 1.0 && o.getChangePercent()<=6).sorted(Comparator.comparingDouble(StockBean::getVolumeCompare).reversed()).collect(Collectors.toList());

            StringBuilder stringBuilder = new StringBuilder();
            String title = "### **"+curDay+"当日首版龙头股" + res.size() + "只股票**\n";
            stringBuilder.append(title);
            List<Stock> resstockBeans  = iStockService.listByCalcTimeAndCalcType(curDay, 3);
            Map<String, Stock> resMap = resstockBeans.stream().collect(Collectors.toMap(Stock::getCode, Function.identity()));
            Map<String,StockDataResponse> stockDataResponseMap = new HashMap<>();
            Map<String,Integer> countMap = new HashMap<>();
            List<String> filterArr = Arrays.asList("转融券标的","标普道琼斯中国","养老金持股","沪股通","融资融券","纳入富时罗素","深股通","标普道琼斯中国","创投","国企改革");
            for (int i = 0; i < res.size(); i++) {
                StockBean stockBean = res.get(i);
                if(stockBean.getName().contains("ST")){
                    continue;
                }
                StockDataResponse stockDataByCode = tencentProxy.getStockDataByCode(stockBean.getCode());
                stockDataResponseMap.put(stockBean.getCode(), stockDataByCode);
                stockDataByCode.getData().getPlate().forEach(o -> {
                    Integer orDefault = countMap.getOrDefault(o.getName(), 0);
                    countMap.put(o.getName(), orDefault+1);
                });
//                stockDataByCode.getData().getConcept().forEach(o -> {
//
//                    Integer orDefault = countMap.getOrDefault(o.getName(), 0);
//                    if(!filterArr.contains(o.getName())){
//                        orDefault++;
//                    }
//                    countMap.put(o.getName(), orDefault);
//                });
                stockBean.setStockData(stockDataByCode);
            }
            for (int i = 0; i < res.size(); i++) {
                StockBean stockBean = res.get(i);
                if(stockBean.getName().contains("ST")){
                    continue;
                }
                int score = 0;
                String plate = "";
                StockDataResponse stockDataByCode = stockBean.getStockData();
                for (int i1 = 0; i1 < stockDataByCode.getData().getPlate().size(); i1++) {
                    StockDataResponse.Plate o = stockDataByCode.getData().getPlate().get(i1);
                    if(countMap.get(o.getName())>1){
                        score++;
                        plate = plate + o.getName();
                    }
                }
//                for (int i1 = 0; i1 < stockDataByCode.getData().getConcept().size(); i1++) {
//                    StockDataResponse.Concept o = stockDataByCode.getData().getConcept().get(i1);
//                    if(countMap.get(o.getName())>1){
//                        score += countMap.get(o.getName());
//                    }
//                }
                stockBean.setScore(score);
                stockBean.setPlate(plate);
            }
            res.sort(Comparator.comparingInt(StockBean::getScore).thenComparing(StockBean::getPlate).thenComparingDouble(StockBean::getVolumeCompare).reversed());

            for (int i = 0; i < res.size(); i++) {
                StockBean stockBean = res.get(i);
                if(stockBean.getName().contains("ST")){
                    continue;
                }
                String weipan = "";
                String jingxuan = "";
                if(isCals && resMap.containsKey(stockBean.getCode())){
                    weipan =  " 收盘：" + resMap.getOrDefault(stockBean.getCode(),new Stock()).getChangePercent() + "";
                    if(ObjectUtil.equal(resMap.getOrDefault(stockBean.getCode(),new Stock()).getPriceMax(),resMap.getOrDefault(stockBean.getCode(),new Stock()).getHighLimit())
                            && ObjectUtil.notEqual(resMap.getOrDefault(stockBean.getCode(),new Stock()).getPriceNow(),resMap.getOrDefault(stockBean.getCode(),new Stock()).getHighLimit())){
                        weipan += " 炸板";
                    }
                }
                Stock stock = lastHighMap.get(stockBean.getCode());

                List<StockDataResponse.Concept> concept = stockBean.getStockData().getData().getConcept();

                // + " 收盘："+weipan

//                stringBuilder.append(String.format("- "+"%s-%s,量比：%s,开盘%s,市值%s,股价:%s,地域:%s,行业:%s\n", stockBean.getName(), stockBean.getCode(), (int)stockBean.getVolumeCompare(), stockBean.getChangePercent(),stockBean.getCirculatingCap(),stockBean.getPriceNow()+weipan,
//                        stockBean.getStockData().getData().getArea().get(0).getName(),
//                        stockBean.getStockData().getData().getPlate().stream().map(o->o.getName()+o.getZdf()).collect(Collectors.joining(",")) + concept.get(0).getZdf()
//                        ));

                
                // 获取昨日早盘量比
                Double lastMorningVolumeCompare = lastMorningVolumeCompareMap.getOrDefault(stockBean.getCode(), 0.0);
                String lastMorningVolumeCompareStr = lastMorningVolumeCompare > 0 ? String.format("%.1f", lastMorningVolumeCompare) : "无";                stringBuilder.append(String.format("- "+"%s-%s,量比：%s,开盘%s,市值%s,股价:%s,昨日尾盘换手:%s,今日开盘换手:%s,昨日尾盘涨跌:%s,昨日早盘量比:%s,地域:%s,行业:%s,风口概念:%s\n", stockBean.getName(), stockBean.getCode(), (int)stockBean.getVolumeCompare(), stockBean.getChangePercent(),stockBean.getCirculatingCap(),stockBean.getPriceNow()+weipan,
                        stock.getExchange(),
                        stockBean.getExchange(),
                        stock.getChangePercent(),
                        lastMorningVolumeCompareStr,
                        stockBean.getStockData().getData().getArea().get(0).getName(),
                        stockBean.getStockData().getData().getPlate().stream().map(StockDataResponse.Plate::getName).collect(Collectors.joining(",")),
                        stockBean.getStockData().getData().getConcept().stream().map(StockDataResponse.Concept::getName).collect(Collectors.joining(","))
                ));

//                stringBuilder.append(String.format("- "+jingxuan+"%s-%s-量比%s,开盘%s,市值%s,股价:%s,早hs:%s,昨hs:%s,昨zd:%s\n", stockBean.getName(), stockBean.getCode(), (int)stockBean.getVolumeCompare(),stockBean.getChangePercent(),stockBean.getCirculatingCap(),stockBean.getPriceNow(),stockBean.getExchange(),stock.getExchange()+weipan,stock.getChangePercent()));
            }
//            DingDingBot.sendMarkDown(title, stringBuilder.toString());
                appendToFile(stringBuilder.toString());

        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }



    /**
     * 量比
     * @param stockBeans
     */
//    @PostConstruct
    public void volumeCompareTest() {

        String[] testDates = new String[]{"2025-02-17"};

        for (int kk = 0; kk < testDates.length; kk++) {
            String curDay = testDates[kk];

            try {
                List<Map<String, Stock>> allOrgStocks = new ArrayList<>();
                String calcDay = curDay;
                for (int i = 1; i <= 20 && allOrgStocks.size() < 6; i++) {
                    // 计算前i天的日期
                    calcDay = getLastGzr(LocalDate.parse(calcDay, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atStartOfDay());
                    // 判断是否为工作日
                    if ("0".equals(HolidayUtil.isWorkingDay(calcDay))) {
                        List<Stock> list1 = iStockService.listByCalcTimeAndCalcType(calcDay,3);
                        if (list1.size() == 0) {
                            break;
                        }
                        // 将股票数据转换为Map并添加到结果列表中
                        Map<String, Stock> stockMap = list1.stream()
                                .collect(Collectors.toMap(Stock::getCode, Function.identity()));

                        allOrgStocks.add(stockMap);
                        if (allOrgStocks.size() >= 5) {
                            break;
                        }
                    }
                }

                List<Stock> stockBeans  = iStockService.listByCalcTimeAndCalcType(curDay, 1);
                //计算昨日涨停
                String lastDay = getLastGzr(LocalDate.parse(curDay, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atStartOfDay());

                List<Stock> lastStocks = iStockService.listByCalcTimeAndCalcType(lastDay, 3);
                //昨日涨停
                Map<String, Stock> lastHighMap = lastStocks.stream().filter(o -> o.getChangePercent() < 11 && ObjectUtil.equal(o.getPriceNow(), o.getHighLimit()) && !o.getName().contains("ST")).collect(Collectors.toMap(Stock::getCode, Function.identity()));
                String lastGzr2 = getLastGzr(LocalDate.parse(lastDay, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atStartOfDay());
                List<Stock> stocks2 = iStockService.listByCalcTimeAndCalcType(lastGzr2, 3);
                //前日涨停
                Map<String, Stock> zhangtingStocks2 = stocks2.stream().filter(o -> o.getChangePercent() < 11 && ObjectUtil.equal(o.getPriceNow(), o.getHighLimit()) && !o.getName().contains("ST")).collect(Collectors.toMap(Stock::getCode, Function.identity()));
                List<Stock> resStock = new ArrayList<>();
                lastHighMap.forEach((key, stock) -> {
                    Stock stock2 = zhangtingStocks2.get(key);
                    if (stock2 == null) {
                        resStock.add(stock);
                    }
                });
                Map<String, Stock> resStockMap = resStock.stream().collect(Collectors.toMap(Stock::getCode, Function.identity()));
                // 获取所有股票代码
                Set<String> codes = resStockMap.keySet();

                Map<String, Stock> stockBeanMap = stockBeans.stream().collect(Collectors.toMap(Stock::getCode, Function.identity()));
                List<Stock> res = new ArrayList<>();
                for (String code : codes) {
                    Stock stockBean = stockBeanMap.get(code);
                    long totalVolume = 0;
                    int count = 0;
                    for (Map<String, Stock> map : allOrgStocks) {
                        String volume = map.get(code).getVolume();
                        totalVolume += Integer.parseInt(volume);
                        count++;
                    }
                    long volume = Long.parseLong(stockBean.getVolume());
                    double compare = volume * count * 240 *1.0f/ totalVolume;
                    stockBean.setVolumeCompare(compare);
                    res.add(stockBean);
                }
                res = res.stream().filter(o -> o.getVolumeCompare() >= 10 && o.getChangePercent() > 1.0 && o.getChangePercent()<6).sorted(Comparator.comparingDouble(Stock::getVolumeCompare).reversed()).collect(Collectors.toList());

                StringBuilder stringBuilder = new StringBuilder();
                String title = "### **"+curDay+"当日接力涨停池" + res.size() + "只股票**\n";
                stringBuilder.append(title);
                List<Stock> resstockBeans  = iStockService.listByCalcTimeAndCalcType(curDay, 3);
                Map<String, Stock> resMap = resstockBeans.stream().collect(Collectors.toMap(Stock::getCode, Function.identity()));
                for (int i = 0; i < res.size(); i++) {
                    Stock stockBean = res.get(i);
                    String weipan = "";
                    if(resMap.containsKey(stockBean.getCode())){
                        weipan = resMap.getOrDefault(stockBean.getCode(),new Stock()).getChangePercent() + "";


                    }
                    stringBuilder.append(String.format("- %s-%s-量比%s,开盘%s,流通市值%s\n", stockBean.getName(), stockBean.getCode(), stockBean.getVolumeCompare() + " 收盘："+weipan,stockBean.getChangePercent(),stockBean.getCirculatingCap()));
                }
//                DingDingBot.sendMarkDown(title, stringBuilder.toString());
                log.info(stringBuilder.toString());

            } catch (ParseException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
